home *** CD-ROM | disk | FTP | other *** search
- ASSEMBLY LANGUAGE VERSION OF A GENERIC INTERRUPT FUNCTION
-
- interrupt(nn,ptr)
- int nn
- struct regs *ptr; /* In this case a long pointer: 32 bytes */
- /**
- In a short C the pointers would be words, not double words, and you'd use a
- "mov bx,[bp+??]" rather than the "lds bx,[bp+???]." In all cases remember to
- recover ds before using bx to point to the base of the structure being
- reloaded with register values.
-
- Also note the rather sneaky way of generating the machine code "CDnn" patch
- that invokes nnth interrupt. Through a irritating omission in the Intel
- instruction set, "int" command can only take an "immediate" or numerical
- argument; and therefore the assembly language programmer must modify the code
- @un(in situ). Not very nice, and certainly not ROM-able, but necessary. What
- I do below is load CD into the AL register, nn into the AH, and then poke the
- word into the code at the proper location. Since the Intel chips use byte-
- reverse layout, the code becomes CDnn. Blush . . . but it works.
- **/
- ASSUME PROPER SEGMENT DECLARATIONS
-
- push bp ;Save bp
- mov bp,sp ;Establish a pointer to the stack
- push ds ;Push whatever other registers need to be saved
- mov al,0cdh ;0CDh into low byte, int # into high
- mov ah,[bp+6] ;This displacement will vary with the compiler
- mov cs:intcall[0],ax ;Stuff CDNN into the instruction site
- lds bx,[bp+8] ;Load seg:ofs of pointer to structure into ds:bx
- mov ax,[bx+0] ;Move first slot of structure into ax
- push [bx+2] ;Push final bx onto stack, since bx needed as
- ; pointer right now.
- mov cx,[bx+4] ;Load the rest of the registers, skipping bp
- mov dx,[bx+6] ; since bp is never used by interrupts and is
- mov di,[bx+8] ; needed to point to stack.
- mov si,[bx+10] ;We can ignore flags on the way IN, not OUT
- mov es,[bx+14]
- mov ds,[bx+16] ;There goes the pointer
- pop bx ;Pop bx off stack
- push bp ;Save bp across interrupt
- intcall:
- dw 00 ;Scene of the crime of self-modifying code
- pop bp ;Recover bp
- push bx ;Save ds & bx so we can use a pointer again
- push ds
- lds bx,[bp+8] ;Reload pointer
- mov [bx+0],ax ;Inverse of above: fill struct with values
- mov [bx+4],cx
- mov [bx+4],cx
- mov [bx+6],dx
- mov [bx+8],di
- mov [bx+10],si
- mov [bx+14],es
- pushf ;Preserve flag value this time
- pop [bx+18] ;When you can't point, pop
- pop [bx+16]
- pop [bx+2]
- pop ds ;Recover saved registers
- pop bp